#pragma once
#include <iostream>
#include <memory>
#include <string>
#include "Sock.hpp"
#include "Protocol.hpp"
using namespace Protocol;
namespace Tcp_server // 类名不能和命名空间名重合
{
    class Tcpserver;
    class ThreadData
    {
    public:
        ThreadData(std::string ip, uint16_t port, int socket, Tcpserver *ts)
            : ip_(ip), port_(port), socket_(socket), ts_(ts)
        {
            ;
        }
        std::string ip_;
        uint16_t port_;
        int socket_;
        Tcpserver *ts_;
    };
    class Tcpserver
    {
    public:
        using func_t = std::function<Response(const Request)>;
        Tcpserver(func_t func, uint16_t port)
            : port_(port), func_(func)
        {
            ;
        }
        void Init()
        {
            sock_.Socket();
            sock_.Bind(port_);
            sock_.Listen();
            log_(ErrorLevel::Debug, "init success: listen sockt:%d", sock_.socket_);
        }
        void ServerIO(std::string ip, uint16_t port, int socket)
        {
            std::string inbuffer;
            while (true)
            {
                // 1 读取数据
                std::string package;
                int n = Readpackage(socket,&inbuffer,&package);
                if (n < 0)
                {    
                    close(socket);
                    exit(READ_ERR);
                }
                else if (n == 0)
                    continue;
                //到了这里就已经读取到了完整的数据报,先去除报头
                package = RemoveHead(package,n);

                // 2 将字符串反序列化
                Request rq;
                rq.Deserialize(package );
                // 3 处理一个请求,并返回结果
                Response rp = func_(rq);
                // 4 将结果序列化
                string send_string;
                rp.serialize(&send_string);

                send_string = AddHead(send_string);
                //发送到网络中
                write(socket,send_string.c_str(),send_string.size());
            }
            // char buffer[1024] = {0};
            // int n = recv(socket,buffer,sizeof(buffer),0);
            // if(n < 0)
            // {
            //     log_(ErrorLevel::Fatal,"Read Err 错误码:%d,错误信息:%s",errno,strerror(errno));
            //     exit(READ_ERR);
            // }
            // //2 将字符串反序列化
            // Request rq;
            // rq.Deserialize(package);
            // //3 处理一个请求,并返回结果
            // Response rp = func_(rq);
            // //4 将结果序列化
            // string send_string;
            // rq.serialize(&send_string);

            // 5 发送到网络中
        }
        static void *threadRoutine(void *arg)
        {
            ThreadData *td = static_cast<ThreadData *>(arg);
            td->ts_->ServerIO(td->ip_, td->port_, td->socket_);
            delete td;
            return nullptr;
        }
        void start() // 接收链接,获取客户端端口号+ip,创建线程执行?
        {
            while (true)
            {
                string ClientIp;
                uint16_t clientport;
                int socket_ = sock_.Accept(&ClientIp, &clientport);
                if (socket_ < 0)
                    continue;
                log_(ErrorLevel::Debug, "get a new client,client info:[%s:%d]",ClientIp.c_str(),clientport);
                // 创建线程,传递端口号和ip
                pthread_t id;
                ThreadData *td = new ThreadData(ClientIp, clientport, socket_, this);
                pthread_create(&id, nullptr, threadRoutine, td);
                
            }
        }

    private:
        func_t func_;
        Log log_;
        Sock sock_;
        uint16_t port_;
    };
};